package edu.buaa;

import java.io.*;
import java.util.*;

public class TopoMap {
    
    public static class Node {
        public String id;
        public double lat;
        public double lon;
        public List<Edge> outEdges;
        public List<Edge> inEdges;
        
        public Node(String id) {
            this.id = id;
            this.outEdges = new ArrayList<>();
            this.inEdges = new ArrayList<>();
        }
    }
    
    public static class Edge {
        public String source;
        public String target;
        public String roadUid;
        public double roadLength;
        public double roadAngle;
        public String roadType;
        
        public Edge(String source, String target, String roadUid, double roadLength, double roadAngle, String roadType) {
            this.source = source;
            this.target = target;
            this.roadUid = roadUid;
            this.roadLength = roadLength;
            this.roadAngle = roadAngle;
            this.roadType = roadType;
        }
    }
    
    private Map<String, Node> nodes;
    private Map<String, Edge> edges;
    
    public TopoMap() {
        this.nodes = new HashMap<>();
        this.edges = new HashMap<>();
    }
    
    public void loadFromCSV(String nodeFile, String edgeFile) throws IOException {
        // 加载节点数据
        try (BufferedReader br = new BufferedReader(new FileReader(nodeFile))) {
            String line = br.readLine(); // 跳过表头
            while ((line = br.readLine()) != null) {
                String[] parts = line.split(",");
                if (parts.length >= 3) {
                    String id = parts[0];
                    Node node = new Node(id);
                    
                    // 从cross_id解析经纬度（这里需要后续补充实际坐标）
                    // 暂时使用默认值，实际实现需要根据数据调整
                    node.lat = 39.905925; // 临时值
                    node.lon = 116.389466; // 临时值
                    
                    nodes.put(id, node);
                }
            }
        }
        
        // 加载边数据
        try (BufferedReader br = new BufferedReader(new FileReader(edgeFile))) {
            String line = br.readLine(); // 跳过表头
            while ((line = br.readLine()) != null) {
                String[] parts = line.split(",");
                if (parts.length >= 11) {
                    String source = parts[0];
                    String target = parts[1];
                    String roadUid = parts[3];
                    double roadLength = Double.parseDouble(parts[9]);
                    double roadAngle = Double.parseDouble(parts[10]);
                    String roadType = parts[8];
                    
                    Edge edge = new Edge(source, target, roadUid, roadLength, roadAngle, roadType);
                    edges.put(source + "->" + target, edge);
                    
                    // 更新节点关系
                    if (nodes.containsKey(source)) {
                        nodes.get(source).outEdges.add(edge);
                    }
                    if (nodes.containsKey(target)) {
                        nodes.get(target).inEdges.add(edge);
                    }
                }
            }
        }
    }
    
    public Node getNode(String id) {
        return nodes.get(id);
    }
    
    public Edge getEdge(String source, String target) {
        return edges.get(source + "->" + target);
    }
    
    public List<Edge> getOutEdges(String nodeId) {
        Node node = nodes.get(nodeId);
        return node != null ? node.outEdges : new ArrayList<>();
    }
    
    public List<Edge> getInEdges(String nodeId) {
        Node node = nodes.get(nodeId);
        return node != null ? node.inEdges : new ArrayList<>();
    }
    
    public Set<String> getAllNodeIds() {
        return nodes.keySet();
    }
    
    public int getNodeCount() {
        return nodes.size();
    }
    
    public int getEdgeCount() {
        return edges.size();
    }
    
    /**
     * 根据GPS坐标和方向距离计算新的GPS坐标
     * @param lat 起始纬度
     * @param lon 起始经度
     * @param distance 距离（米）
     * @param angle 方向角度（与正北方向夹角，单位：度）
     * @return 新的GPS坐标 [lat, lon]
     */
    public static double[] calculateNewPosition(double lat, double lon, double distance, double angle) {
        // 将角度转换为弧度
        double angleRad = Math.toRadians(angle);
        
        // 地球半径（米）
        final double EARTH_RADIUS = 6371000;
        
        // 计算在地球表面的位移（弧度）
        double deltaLat = distance * Math.cos(angleRad) / EARTH_RADIUS;
        double deltaLon = distance * Math.sin(angleRad) / (EARTH_RADIUS * Math.cos(Math.toRadians(lat)));
        
        // 转换为度并计算新坐标
        double newLat = lat + Math.toDegrees(deltaLat);
        double newLon = lon + Math.toDegrees(deltaLon);
        
        return new double[]{newLat, newLon};
    }
    
    public static void main(String[] args) {
        try {
            TopoMap topoMap = new TopoMap();
            topoMap.loadFromCSV("topo-node.csv", "topo-edge.csv");
            
            System.out.println("加载完成！");
            System.out.println("节点数量: " + topoMap.getNodeCount());
            System.out.println("边数量: " + topoMap.getEdgeCount());
            
            // 测试节点查找
            String testNodeId = "029362";
            Node node = topoMap.getNode(testNodeId);
            if (node != null) {
                System.out.println("找到节点: " + testNodeId);
                System.out.println("出边数量: " + node.outEdges.size());
                System.out.println("入边数量: " + node.inEdges.size());
                
                // 测试GPS坐标计算
                double[] newPos = calculateNewPosition(39.905925, 116.389466, 100, 90);
                System.out.println("从(39.905925, 116.389466)向东100米后的位置: " + 
                                 newPos[0] + ", " + newPos[1]);
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}